<html>
<head><meta charset="utf-8"><title>Stabilizing `proc_macro::Span::join` · t-lang · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/index.html">t-lang</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60.html">Stabilizing `proc_macro::Span::join`</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="242497201"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stabilizing%20%60proc_macro%3A%3ASpan%3A%3Ajoin%60/near/242497201" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60.html#242497201">(Jun 13 2021 at 07:58)</a>:</h4>
<p>Any opposition to a PR that would stabilize <code>proc_macro::Span::join</code> alone? The only concern I see in <a href="https://github.com/rust-lang/rust/issues/54725">#54725</a> is the behavior when hygiene doesn't match. After testing it on nightly, it works exactly as I'd expect — the method returns <code>None</code> when they don't match semantically (mixed site depends on the situation, naturally). It's a small API that has plenty of use cases for diagnostics, even just <code>compile_error!</code> ones.</p>



<a name="242498467"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stabilizing%20%60proc_macro%3A%3ASpan%3A%3Ajoin%60/near/242498467" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60.html#242498467">(Jun 13 2021 at 08:34)</a>:</h4>
<p>Another option would be to, based on the <code>.located_at(...)</code> method, offer a specialized join utility affecting locations only, not "resolved at" semantics</p>



<a name="242498485"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stabilizing%20%60proc_macro%3A%3ASpan%3A%3Ajoin%60/near/242498485" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60.html#242498485">(Jun 13 2021 at 08:35)</a>:</h4>
<p>I suppose that could work, and would avoid the need to return an <code>Option&lt;Span&gt;</code>. I was more checking the temperature with regard to stabilizing the existing method, though. There hasn't been much discussion on it at all from what I can see.</p>



<a name="243547503"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stabilizing%20%60proc_macro%3A%3ASpan%3A%3Ajoin%60/near/243547503" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60.html#243547503">(Jun 22 2021 at 17:06)</a>:</h4>
<p>I haven't really seen any use of <code>join</code> where there was a good way to react to <code>None</code>. Returning just one of the spans or some dummy span instead isn't great either, but I'm not sure a Option&lt;Span&gt;-returning function will be great.</p>



<a name="243766303"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stabilizing%20%60proc_macro%3A%3ASpan%3A%3Ajoin%60/near/243766303" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60.html#243766303">(Jun 24 2021 at 10:31)</a>:</h4>
<p>Is there a situation wherein the different hygienes/files is <em>not</em> programmer error? If it always is a programmer error, it would be sensible to just panic.</p>



<a name="243800925"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stabilizing%20%60proc_macro%3A%3ASpan%3A%3Ajoin%60/near/243800925" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60.html#243800925">(Jun 24 2021 at 15:12)</a>:</h4>
<p>If you're trying to replicate some of the logic done by the compiler (e.g. creating a span for an item by joining individual token spans), then you can legitimately run into this</p>



<a name="243801015"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stabilizing%20%60proc_macro%3A%3ASpan%3A%3Ajoin%60/near/243801015" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60.html#243801015">(Jun 24 2021 at 15:13)</a>:</h4>
<p>For example, you could have something like <code>pub fn foo() {}</code>, where each token has a span from a different file</p>



<a name="243858479"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stabilizing%20%60proc_macro%3A%3ASpan%3A%3Ajoin%60/near/243858479" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60.html#243858479">(Jun 24 2021 at 23:20)</a>:</h4>
<p>Could you explain where that would come up? I've only done relatively basic proc macros myself, so I admittedly don't know have the most experience.</p>



<a name="243865321"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stabilizing%20%60proc_macro%3A%3ASpan%3A%3Ajoin%60/near/243865321" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60.html#243865321">(Jun 25 2021 at 00:58)</a>:</h4>
<p>The combination of spans from different files happens when a proc-macro uses some interpolated tokens</p>



<a name="243865327"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stabilizing%20%60proc_macro%3A%3ASpan%3A%3Ajoin%60/near/243865327" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60.html#243865327">(Jun 25 2021 at 00:59)</a>:</h4>
<p>e.g. if it expands to <code>$vis fn foo() {}</code></p>



<a name="243865426"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stabilizing%20%60proc_macro%3A%3ASpan%3A%3Ajoin%60/near/243865426" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60.html#243865426">(Jun 25 2021 at 01:01)</a>:</h4>
<p>Sure, but where would <code>Span::join</code> be needed for that? I get that different hygienes exist, I just don't see where you'd even <em>attempt</em> to join them together.</p>



<a name="243950832"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stabilizing%20%60proc_macro%3A%3ASpan%3A%3Ajoin%60/near/243950832" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60.html#243950832">(Jun 25 2021 at 18:08)</a>:</h4>
<p>I see. I'm not aware of any concrete examples, but it seems plausible that a proc-macro could do so for diagnostic purposes (e.g. pointing to the function header span)</p>



<a name="243959418"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stabilizing%20%60proc_macro%3A%3ASpan%3A%3Ajoin%60/near/243959418" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60.html#243959418">(Jun 25 2021 at 19:25)</a>:</h4>
<p><span class="user-mention silent" data-user-id="245610">Jacob Pratt</span> <a href="#narrow/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60/near/243766303">said</a>:</p>
<blockquote>
<p>Is there a situation wherein the different hygienes/files is <em>not</em> programmer error? If it always is a programmer error, it would be sensible to just panic.</p>
</blockquote>
<p>the compiler itself joins spans from different files/contexts all the time. (causing some interesting results sometimes ^^')</p>



<a name="243959689"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stabilizing%20%60proc_macro%3A%3ASpan%3A%3Ajoin%60/near/243959689" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60.html#243959689">(Jun 25 2021 at 19:27)</a>:</h4>
<p>say i have <code>macro_rules! my_assert_eq { ($a:expr, $b:expr) =&gt; { my_assert!($a == $b) }; }</code>, then my <code>my_assert</code> proc_macro gets an expression with three different contexts. it might want to give an error about the whole <code>$a == $b</code> expression. but  the span of that expression spans up to three files and hygiene contexts.</p>



<a name="243961139"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stabilizing%20%60proc_macro%3A%3ASpan%3A%3Ajoin%60/near/243961139" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60.html#243961139">(Jun 25 2021 at 19:39)</a>:</h4>
<p>a good example of a proc macro that should use <code>Span::join</code> is <code>paste!</code> since it creates new identifiers from concatenating existing identifiers and <em>should</em> preserve their hygiene</p>



<a name="243961564"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stabilizing%20%60proc_macro%3A%3ASpan%3A%3Ajoin%60/near/243961564" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mara <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60.html#243961564">(Jun 25 2021 at 19:43)</a>:</h4>
<p>even that can be very tricky! a macro might look at the name of a type and make a new type with a prefix or something. so you'd paste <code>prefix_</code> and whatever the name of the struct is that came in. then paste!() would get two tokens from different contexts</p>



<a name="243961957"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stabilizing%20%60proc_macro%3A%3ASpan%3A%3Ajoin%60/near/243961957" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60.html#243961957">(Jun 25 2021 at 19:46)</a>:</h4>
<p>after looking at the source, <code>paste!</code> actually uses the span of the <code>[]</code> in a token paste sequence <code>[&lt;a b c&gt;]</code></p>



<a name="243982191"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Stabilizing%20%60proc_macro%3A%3ASpan%3A%3Ajoin%60/near/243982191" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Pratt <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Stabilizing.20.60proc_macro.3A.3ASpan.3A.3Ajoin.60.html#243982191">(Jun 25 2021 at 23:38)</a>:</h4>
<p><code>paste!</code> would likely use the correct span if it possible. Aside from just picking one of the two <code>Span</code>s, what could a user feasibly do? That's pretty much the only thing I can think of doing, in which case returning an <code>Option&lt;Span&gt;</code> would be sufficient to give the user control.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>